/*
  Copyright 2011 Tobias "Tomoko" Platen

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "sekai/VoiceSampler.h"

// FIXME: do not hardcode
#define factor 4
#define delay 0
#include <sndfile.h>
#include <boost/filesystem.hpp>

VoiceSampler::VoiceSampler(int buffer_size) : OLABuffer(buffer_size) {}

VoiceSampler::~VoiceSampler() {}

bool VoiceSampler::readData(float *data, int size, int fill) {
  // TODO: fill if no data
  while (!isFilled(fill)) {
    if (addOnePulse() == false)
      return false;
  }

  pop(data, size);
  return true;
}

int VoiceSampler::findPitchMark(struct Track& track,float pos,struct Pitch& p0,struct Pitch& p1,float* out)
{
     int count = track.getPitchCount();
     for(int i=0;i<count-1;i++)
     {
         p0 = track.getPitch(i);
         p1 = track.getPitch(i+1);
         if(p0.pos <= pos && p1.pos > pos)
         {
            if(out) *out = (pos-p0.pos)/(p1.pos-p0.pos);
            return i;
         }
     }
     return -1;
}

bool VoiceSampler::load(struct VoiceRecord& record,int& samplerate,std::string fileName){
    
          std::string f0 = boost::filesystem::change_extension(fileName, ".f0").string();
          std::string pmk = boost::filesystem::change_extension(fileName, ".pmk").string();
          
          record.f0Track.readFromFile(f0);
          record.pmkTrack.readFromFile(pmk);
          
          SF_INFO info={0};
          SNDFILE* sf = sf_open(fileName.c_str(),SFM_READ,&info);
          if(sf==nullptr) return false;
          record.input_data = new float[info.frames];
          record.input_data_length = info.frames;
          assert(info.channels==1);
          samplerate = info.samplerate;
          sf_read_float(sf,record.input_data,info.frames);
          sf_close(sf);
          return true;
}

void VoiceSampler::hanningWindow(float* signal,int size)
{   
    //see https://github.com/numediart/MBROLA/blob/master/Engine/mbrola.c for reference
    for (int i=0; i<size; i++)
        signal[i] *= (0.5 * (1.0 - cos((double)i*2*M_PI/(float)size)));
}
